<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="utf-8"/>
<title>C#创建服务及使用程序自动安装服务，.NET创建一个即是可执行程序又是Windows服务的exe - 曾元军 - 博客园</title>
<link type="text/css" rel="stylesheet" href="/bundles/blog-common.css?v=Jsknfrse2BShd-7DrxM42RyulObn44e4JjkI6-WX6zk1"/>
<link id="MainCss" type="text/css" rel="stylesheet" href="/skins/darkgreentrip/bundle-darkgreentrip.css?v=xPXJVC4GCITs1yYYgSeLkcicCxapqseaPVQLFGMO1wc1"/>
<link title="RSS" type="application/rss+xml" rel="alternate" href="http://www.cnblogs.com/yzeng/rss"/>
<link title="RSD" type="application/rsd+xml" rel="EditURI" href="http://www.cnblogs.com/yzeng/rsd.xml"/>
<link type="application/wlwmanifest+xml" rel="wlwmanifest" href="http://www.cnblogs.com/yzeng/wlwmanifest.xml"/>
<script src="http://common.cnblogs.com/script/jquery.js" type="text/javascript"></script>  
<script type="text/javascript">var currentBlogApp = 'yzeng', cb_enable_mathjax=false;</script>
<script src="/bundles/blog-common.js?v=V3tkfsuahqfUzgmqZVwj2QjsxodIvgDfvPKdn8yDuMY1" type="text/javascript"></script>
</head>
<body>
<a name="top"></a>
<div id="page_begin_html"></div><script>load_page_begin_html();</script>

<!--done-->
<div id="home">
<div id="header">
	<div id="blogTitle">
	<a id="lnkBlogLogo" href="http://www.cnblogs.com/yzeng/"><img id="blogLogo" src="/Skins/custom/images/logo.gif" alt="返回主页" /></a>			
		
<!--done-->
<h1><a id="Header1_HeaderTitle" class="headermaintitle" href="http://www.cnblogs.com/yzeng/">曾元军-技术分享</a></h1>
<h2>【茫茫人海，相遇是缘】微信：zyj--wx</h2>



		
	</div><!--end: blogTitle 博客的标题和副标题 -->
	<div id="navigator">
		
<ul id="navList">
<li><a id="MyLinks1_HomeLink" class="menu" href="http://www.cnblogs.com/">博客园</a></li>
<li><a id="MyLinks1_MyHomeLink" class="menu" href="http://www.cnblogs.com/yzeng/">首页</a></li>
<li><a id="MyLinks1_NewPostLink" class="menu" rel="nofollow" href="http://i.cnblogs.com/EditPosts.aspx?opt=1">新随笔</a></li>
<li><a id="MyLinks1_ContactLink" class="menu" rel="nofollow" href="http://msg.cnblogs.com/send/%E6%9B%BE%E5%85%83%E5%86%9B">联系</a></li>
<li><a id="MyLinks1_Syndication" class="menu" href="http://www.cnblogs.com/yzeng/rss">订阅</a>
<!--<a id="MyLinks1_XMLLink" class="aHeaderXML" href="http://www.cnblogs.com/yzeng/rss"><img src="http://www.cnblogs.com/images/xml.gif" alt="订阅" /></a>--></li>
<li><a id="MyLinks1_Admin" class="menu" rel="nofollow" href="http://i.cnblogs.com/">管理</a></li>
</ul>
		<div class="blogStats">
			
			
<!--done-->
随笔- 38&nbsp;
文章- 0&nbsp;
评论- 70&nbsp;

			
		</div><!--end: blogStats -->
	</div><!--end: navigator 博客导航栏 -->
</div><!--end: header 头部 -->

<div id="main">
	<div id="mainContent">
	<div class="forFlow">
		
<div id="post_detail">
<!--done-->
<div id="topics">
	<div class = "post">
		<h1 class = "postTitle">
			<a id="cb_post_title_url" class="postTitle2" href="http://www.cnblogs.com/yzeng/p/4205533.html">C#创建服务及使用程序自动安装服务，.NET创建一个即是可执行程序又是Windows服务的exe</a>
		</h1>
		<div class="clear"></div>
		<div class="postBody">
			<div id="cnblogs_post_body"><p>不得不说，.NET中安装服务很麻烦，即要创建Service，又要创建ServiceInstall，最后还要弄一堆命令来安装和卸载。</p>
<p>今天给大家提供一种方式，直接使用我们的程序来安装/卸载服务，并且可以<strong>让一个exe即能直接运行也行安装为windows服务</strong></p>
<p><strong><br /><span style="color: #993300;">首先我们创建一个Windows应用程序，（我创建的是控制台程序，WinForm也一样）</span></strong></p>
<p><strong><span style="color: #993300;"><img src="http://images.cnitblog.com/blog/403207/201501/061035476257344.png" alt="" /></span></strong></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><strong><span style="color: #993300;">接下来在项目中添加一个Windows服务类</span></strong></p>
<p><img src="http://images.cnitblog.com/blog/403207/201501/061036421258961.png" alt="" /></p>
<p><img src="http://images.cnitblog.com/blog/403207/201501/061037092348513.png" alt="" /></p>
<p>&nbsp;</p>
<p><strong><span style="color: #993300;">然后双击&ldquo;MainService.cs&rdquo;，在上面点右键&ldquo;打开代码&rdquo;</span></strong></p>
<p>&nbsp;</p>
<p><img src="http://images.cnitblog.com/blog/403207/201501/061037279377799.png" alt="" /></p>
<p><strong><span style="color: #993300;">这里面写服务的具体实现，以下是我写的示例代码</span></strong></p>
<div class="cnblogs_code">
<pre> <span style="color: #0000ff;">partial</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> MainService : ServiceBase
    {
        </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> MainService()
        {
            InitializeComponent();
        }

        </span><span style="color: #0000ff;">protected</span> <span style="color: #0000ff;">override</span> <span style="color: #0000ff;">void</span> OnStart(<span style="color: #0000ff;">string</span><span style="color: #000000;">[] args)
        {
            </span><span style="color: #008000;">//</span><span style="color: #008000;"> TODO:  在此处添加代码以启动服务。</span>
            System.IO.File.AppendAllText(<span style="color: #800000;">"</span><span style="color: #800000;">D:\\log.txt</span><span style="color: #800000;">"</span>, <span style="color: #800000;">"</span><span style="color: #800000;">服务已启动&hellip;&hellip;</span><span style="color: #800000;">"</span> +<span style="color: #000000;"> DateTime.Now.ToString());
        }

        </span><span style="color: #0000ff;">protected</span> <span style="color: #0000ff;">override</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> OnStop()
        {
            </span><span style="color: #008000;">//</span><span style="color: #008000;"> TODO:  在此处添加代码以执行停止服务所需的关闭操作。</span>
            System.IO.File.AppendAllText(<span style="color: #800000;">"</span><span style="color: #800000;">D:\\log.txt</span><span style="color: #800000;">"</span>, <span style="color: #800000;">"</span><span style="color: #800000;">服务已停止&hellip;&hellip;</span><span style="color: #800000;">"</span> +<span style="color: #000000;"> DateTime.Now.ToString());
        }
    }</span></pre>
</div>
<p><strong><span style="color: #993300;">然后我们改程序入口Main方法，让其在启动时识别是Windows应用程序还是Windows服务，如果是应用程序就执行应用程序的代码，如果是服务就执行MainService的代码</span></strong></p>
<p>如果是服务，我给了一个"s"参数，如果有这个参数就证明是Windows服务，然后启动MainService</p>
<div class="cnblogs_code">
<pre> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> Main(<span style="color: #0000ff;">string</span><span style="color: #000000;">[] args)
        {
           </span><span style="color: #008000;">//</span><span style="color: #008000;">如果传递了"s"参数就启动服务</span>
            <span style="color: #0000ff;">if</span> (args.Length &gt; <span style="color: #800080;">0</span> &amp;&amp; args[<span style="color: #800080;">0</span>] == <span style="color: #800000;">"</span><span style="color: #800000;">s</span><span style="color: #800000;">"</span><span style="color: #000000;">)
            {
               </span><span style="color: #008000;">//</span><span style="color: #008000;">启动服务的代码，可以从其它地方拷贝</span>
<span style="color: #000000;">                ServiceBase[] ServicesToRun;
                ServicesToRun </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> ServiceBase[] 
                { 
                    </span><span style="color: #0000ff;">new</span><span style="color: #000000;"> MainService(),
                };
                ServiceBase.Run(ServicesToRun);
            }
            </span><span style="color: #0000ff;">else</span><span style="color: #000000;">
            {}</span></pre>
</div>
<p>然后，我们再实现应用程序的功能，就是上面的else语句块，应用程序的功能就是安装/卸载服务，可以用windows自带的sc命令来进行安装和卸载，具体代码如下：</p>
<div class="cnblogs_code">
<pre>                Console.WriteLine(<span style="color: #800000;">"</span><span style="color: #800000;">这是Windows应用程序</span><span style="color: #800000;">"</span><span style="color: #000000;">);
                Console.WriteLine(</span><span style="color: #800000;">"</span><span style="color: #800000;">请选择，[1]安装服务 [2]卸载服务 [3]退出</span><span style="color: #800000;">"</span><span style="color: #000000;">);
                </span><span style="color: #0000ff;">var</span> rs = <span style="color: #0000ff;">int</span><span style="color: #000000;">.Parse(Console.ReadLine());
                </span><span style="color: #0000ff;">switch</span><span style="color: #000000;"> (rs)
                {
                    </span><span style="color: #0000ff;">case</span> <span style="color: #800080;">1</span><span style="color: #000000;">:
                        </span><span style="color: #008000;">//</span><span style="color: #008000;">取当前可执行文件路径，加上"s"参数，证明是从windows服务启动该程序</span>
                        <span style="color: #0000ff;">var</span> path = Process.GetCurrentProcess().MainModule.FileName + <span style="color: #800000;">"</span><span style="color: #800000;"> s</span><span style="color: #800000;">"</span><span style="color: #000000;">;
                        Process.Start(</span><span style="color: #800000;">"</span><span style="color: #800000;">sc</span><span style="color: #800000;">"</span>, <span style="color: #800000;">"</span><span style="color: #800000;">create myserver binpath= \"</span><span style="color: #800000;">"</span> + path + <span style="color: #800000;">"</span><span style="color: #800000;">\" displayName= 我的服务 start= auto</span><span style="color: #800000;">"</span><span style="color: #000000;">);
                        Console.WriteLine(</span><span style="color: #800000;">"</span><span style="color: #800000;">安装成功</span><span style="color: #800000;">"</span><span style="color: #000000;">);
                        Console.Read();
                        </span><span style="color: #0000ff;">break</span><span style="color: #000000;">;
                    </span><span style="color: #0000ff;">case</span> <span style="color: #800080;">2</span><span style="color: #000000;">:
                        Process.Start(</span><span style="color: #800000;">"</span><span style="color: #800000;">sc</span><span style="color: #800000;">"</span>, <span style="color: #800000;">"</span><span style="color: #800000;">delete myserver</span><span style="color: #800000;">"</span><span style="color: #000000;">);
                        Console.WriteLine(</span><span style="color: #800000;">"</span><span style="color: #800000;">卸载成功</span><span style="color: #800000;">"</span><span style="color: #000000;">);
                        Console.Read();
                        </span><span style="color: #0000ff;">break</span><span style="color: #000000;">;
                    </span><span style="color: #0000ff;">case</span> <span style="color: #800080;">3</span>: <span style="color: #0000ff;">break</span><span style="color: #000000;">;
                }</span></pre>
</div>
<p>这样我们就实现了一个即是可执行程序又是Windows服务的应用程序</p>
<p>Main方法完整代码如下</p>
<div class="cnblogs_code">
<pre> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> Main(<span style="color: #0000ff;">string</span><span style="color: #000000;">[] args)
        {
            </span><span style="color: #0000ff;">if</span> (args.Length &gt; <span style="color: #800080;">0</span> &amp;&amp; args[<span style="color: #800080;">0</span>] == <span style="color: #800000;">"</span><span style="color: #800000;">s</span><span style="color: #800000;">"</span><span style="color: #000000;">)
            {
                ServiceBase[] ServicesToRun;
                ServicesToRun </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> ServiceBase[] 
                { 
                    </span><span style="color: #0000ff;">new</span><span style="color: #000000;"> MainService(),
                };
                ServiceBase.Run(ServicesToRun);
            }
            </span><span style="color: #0000ff;">else</span><span style="color: #000000;">
            {
                Console.WriteLine(</span><span style="color: #800000;">"</span><span style="color: #800000;">这是Windows应用程序</span><span style="color: #800000;">"</span><span style="color: #000000;">);
                Console.WriteLine(</span><span style="color: #800000;">"</span><span style="color: #800000;">请选择，[1]安装服务 [2]卸载服务 [3]退出</span><span style="color: #800000;">"</span><span style="color: #000000;">);
                </span><span style="color: #0000ff;">var</span> rs = <span style="color: #0000ff;">int</span><span style="color: #000000;">.Parse(Console.ReadLine());
                </span><span style="color: #0000ff;">switch</span><span style="color: #000000;"> (rs)
                {
                    </span><span style="color: #0000ff;">case</span> <span style="color: #800080;">1</span><span style="color: #000000;">:
                        </span><span style="color: #008000;">//</span><span style="color: #008000;">取当前可执行文件路径，加上"s"参数，证明是从windows服务启动该程序</span>
                        <span style="color: #0000ff;">var</span> path = Process.GetCurrentProcess().MainModule.FileName + <span style="color: #800000;">"</span><span style="color: #800000;"> s</span><span style="color: #800000;">"</span><span style="color: #000000;">;
                        Process.Start(</span><span style="color: #800000;">"</span><span style="color: #800000;">sc</span><span style="color: #800000;">"</span>, <span style="color: #800000;">"</span><span style="color: #800000;">create myserver binpath= \"</span><span style="color: #800000;">"</span> + path + <span style="color: #800000;">"</span><span style="color: #800000;">\" displayName= 我的服务 start= auto</span><span style="color: #800000;">"</span><span style="color: #000000;">);
                        Console.WriteLine(</span><span style="color: #800000;">"</span><span style="color: #800000;">安装成功</span><span style="color: #800000;">"</span><span style="color: #000000;">);
                        Console.Read();
                        </span><span style="color: #0000ff;">break</span><span style="color: #000000;">;
                    </span><span style="color: #0000ff;">case</span> <span style="color: #800080;">2</span><span style="color: #000000;">:
                        Process.Start(</span><span style="color: #800000;">"</span><span style="color: #800000;">sc</span><span style="color: #800000;">"</span>, <span style="color: #800000;">"</span><span style="color: #800000;">delete myserver</span><span style="color: #800000;">"</span><span style="color: #000000;">);
                        Console.WriteLine(</span><span style="color: #800000;">"</span><span style="color: #800000;">卸载成功</span><span style="color: #800000;">"</span><span style="color: #000000;">);
                        Console.Read();
                        </span><span style="color: #0000ff;">break</span><span style="color: #000000;">;
                    </span><span style="color: #0000ff;">case</span> <span style="color: #800080;">3</span>: <span style="color: #0000ff;">break</span><span style="color: #000000;">;
                }
            }
        }</span></pre>
</div>
<p><strong><span style="color: #993300;">至此，程序已基本写完，接下来我们测试一下</span></strong></p>
<p><strong><span style="color: #993300;">直接双击ServiceOrApp.exe</span></strong></p>
<p><strong><span style="color: #993300;"><img src="http://images.cnitblog.com/blog/403207/201501/061047162652762.png" alt="" /></span></strong></p>
<p>&nbsp;</p>
<p><strong><span style="color: #993300;">输入 1</span></strong></p>
<p><img src="http://images.cnitblog.com/blog/403207/201501/061047410464757.png" alt="" /></p>
<p><strong><span style="color: #993300;">提示安装成功，然后运行&ldquo;services.msc"打开服务管理器</span></strong></p>
<p><img src="http://images.cnitblog.com/blog/403207/201501/061048296565608.png" alt="" /></p>
<p><strong><span style="color: #993300;">可以发现我们的服务已安装成功，然后右键启动服务</span></strong></p>
<p><strong><span style="color: #993300;"><img src="http://images.cnitblog.com/blog/403207/201501/061049085629921.png" alt="" /></span></strong></p>
<p>&nbsp;</p>
<p><strong><span style="color: #993300;">成功启动</span></strong></p>
<p><img src="http://images.cnitblog.com/blog/403207/201501/061049420003938.png" alt="" /></p>
<p><strong><span style="color: #993300;">然后去D盘看看log.txt</span></strong></p>
<p><strong><span style="color: #993300;"><img src="http://images.cnitblog.com/blog/403207/201501/061050147507799.png" alt="" /></span></strong></p>
<p>&nbsp;</p>
<p><strong><span style="color: #993300;">说明服务执行正常</span></strong></p>
<p><strong><span style="color: #993300;">我们再停止服务</span></strong></p>
<p><strong><span style="color: #993300;"><img src="http://images.cnitblog.com/blog/403207/201501/061050484531503.png" alt="" /></span></strong></p>
<p>&nbsp;</p>
<p><strong><span style="color: #993300;">成功停止后再看看D盘的log.txt文件</span></strong></p>
<p><strong><span style="color: #993300;"><img src="http://images.cnitblog.com/blog/403207/201501/061051333289026.png" alt="" /></span></strong></p>
<p>&nbsp;</p>
<p><strong><span style="color: #993300;">看到以上内容，说明服务启动和停止都没问题（忘了输出换行符 - -！）</span></strong></p>
<p><strong><span style="color: #993300;">然后我们再试一下卸载服务，还是双击ServiceOrApp.exe，选择2</span></strong></p>
<p><strong><span style="color: #993300;"><img src="http://images.cnitblog.com/blog/403207/201501/061053073288842.png" alt="" /></span></strong></p>
<p>&nbsp;</p>
<p><span style="color: #993300;"><strong>提示卸载成功，然后再运行&ldquo;services.msc"打开服务管理器</strong></span></p>
<p><strong><img src="http://images.cnitblog.com/blog/403207/201501/061053434535373.png" alt="" /></strong></p>
<p>&nbsp;</p>
<p><strong><span style="color: #993300;">可以看到已经没有&rdquo;我的服务&ldquo;了，已成功卸载</span></strong></p>
<p><span style="color: #339966;">这里安装和卸载主要运用了windows的sc命令，然后使用启动参数来判断是服务还是程序以执行不同的代码</span></p>
<p>&nbsp;</p></div><div id="MySignature"></div>
<div class="clear"></div>
<div id="blog_post_info_block">
<div id="BlogPostCategory"></div>
<div id="EntryTag"></div>
<div id="blog_post_info">
</div>
<div class="clear"></div>
<div id="post_next_prev"></div>
</div>


		</div>
		<div class = "postDesc">posted @ <span id="post-date">2015-01-06 10:56</span> <a href='http://www.cnblogs.com/yzeng/'>曾元军</a> 阅读(<span id="post_view_count">...</span>) 评论(<span id="post_comment_count">...</span>)  <a href ="http://i.cnblogs.com/EditPosts.aspx?postid=4205533" rel="nofollow">编辑</a> <a href="#" onclick="AddToWz(4205533);return false;">收藏</a></div>
	</div>
	<script type="text/javascript">var allowComments=true,isLogined=false,cb_blogId=116579,cb_entryId=4205533,cb_blogApp=currentBlogApp,cb_blogUserGuid='b80ef1d8-ae8e-e111-aa3f-842b2b196315',cb_entryCreatedDate='2015/1/6 10:56:00';loadViewCount(cb_entryId);</script>
	
</div><!--end: topics 文章、评论容器-->
</div><a name="!comments"></a><div id="blog-comments-placeholder"></div><script type="text/javascript">var commentManager = new blogCommentManager();commentManager.renderComments(0);</script>
<div id='comment_form' class='commentform'>
<a name='commentform'></a>
<div id='divCommentShow'></div>
<div id='comment_nav'><span id='span_refresh_tips'></span><a href='javascript:void(0);' onclick='return RefreshCommentList();' id='lnk_RefreshComments' runat='server' clientidmode='Static'>刷新评论</a><a href='#' onclick='return RefreshPage();'>刷新页面</a><a href='#top'>返回顶部</a></div>
<div id='comment_form_container'></div>
<div class='ad_text_commentbox' id='ad_text_under_commentbox'></div>
<div id='ad_t2'></div>
<div id='opt_under_post'></div>
<div id='ad_c1' class='c_ad_block'></div>
<div id='under_post_news'></div>
<div id='under_post_kb'></div>
<div id='HistoryToday' class='c_ad_block'></div>
<script type='text/javascript'>
$(function () {
    setTimeout(function () { incrementViewCount(cb_entryId); }, 50);
    deliverAdT2();
    deliverAdC1();    
    loadNewsAndKb();
    loadBlogSignature();
    LoadPostInfoBlock(cb_blogId, cb_entryId, cb_blogApp, cb_blogUserGuid);
    GetPrevNextPost(cb_entryId, cb_blogId, cb_entryCreatedDate);
    loadOptUnderPost();
    GetHistoryToday(cb_blogId, cb_blogApp, cb_entryCreatedDate);    
});
</script>
</div>


	</div><!--end: forFlow -->
	</div><!--end: mainContent 主体内容容器-->

	<div id="sideBar">
		<div id="sideBarMain">
			
<!--done-->
<div class="newsItem">
<h3 class="catListTitle">公告</h3>
	<div id="blog-news"></div><script type="text/javascript">loadBlogNews();</script>
</div>

			<div id="blog-calendar" style="display:none"></div><script type="text/javascript">loadBlogDefaultCalendar();</script>
			
			<div id="leftcontentcontainer">
				<div id="blog-sidecolumn"></div><script type="text/javascript">loadBlogSideColumn();</script>
			</div>
			
		</div><!--end: sideBarMain -->
	</div><!--end: sideBar 侧边栏容器 -->
	<div class="clear"></div>
	</div><!--end: main -->
	<div class="clear"></div>
	<div id="footer">
		
<!--done-->
Copyright &copy;2016 曾元军
	</div><!--end: footer -->
</div><!--end: home 自定义的最大容器 -->
<!--PageEndHtml Block Begin-->
<script type="text/javascript">var cnzz_protocol = (("https:" == document.location.protocol) ? " https://" : " http://");document.write(unescape("%3Cspan id='cnzz_stat_icon_1000500909'%3E%3C/span%3E%3Cscript src='" + cnzz_protocol + "s11.cnzz.com/z_stat.php%3Fid%3D1000500909%26online%3D1%26show%3Dline' type='text/javascript'%3E%3C/script%3E"));</script>
<!--PageEndHtml Block End-->
</body>
</html>
